package com.cysyz.mylib.sms.impl;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import com.cysyz.mylib.sms.SMSRegisterConfig;
import com.cysyz.mylib.sms.SMSSender;
import com.cysyz.mylib.sms.SmsSendLogAble;
import com.cysyz.mylib.sms.SmsSendLogService;
import com.cysyz.mylib.sms.engine.BUCPClient;
import com.cysyz.mylib.sms.exception.SMSException;
import com.cysyz.mylib.utils.MyStringUtils;
import com.cysyz.mylib.utils.myassert.MyAssert;

public class SMSSenderBUCPImpl implements SMSSender{
	@Resource
	private BUCPClient bucpClient;
	@Resource
	private SmsSendLogService smsSendLogService;
	
	@SuppressWarnings("rawtypes")
	private Class clazz;
	
	public <T extends SmsSendLogAble> SMSSenderBUCPImpl(Class<T> clazz) {
		this.clazz = clazz;
	}
	@Override
	public String sendOneMsgToOnePerson(String phoneNum, String content) throws SMSException {
		return sendMsg(phoneNum, content, null);
	}

	@Override
	public String sendOneMsgToSomePerson(List<String> phoneNums, String content) throws SMSException {
		String phoneNumsCsv = MyStringUtils.listToCsv(phoneNums);
		return sendMsg(phoneNumsCsv, content, null);
	}
	
	@Override
	public String sendOneMsgToSomePerson(String phoneNumsCsv, String content) throws SMSException {
		return sendMsg(phoneNumsCsv, content, null);
	}
	
	@Override
	public String sendOneMsgToSomePersonTiming(List<String> phoneNums, String content, String stime) throws SMSException {
		String phoneNumsCsv = MyStringUtils.listToCsv(phoneNums);
		return this.sendMsg(phoneNumsCsv, content, stime);
	}

	@Override
	public String sendOneMsgToSomePersonTiming(String phoneNumsCsv, String content, String stime) throws SMSException {
		return this.sendMsg(phoneNumsCsv, content, stime);
	}
	
	@Override
	public String sendSomeMsgToSomePerson(List<String> phoneNums,
			List<String> contents) throws SMSException {
		return sendSomeMsgToSomePerson(phoneNums, contents, null);
	}
	
	@Override
	public String sendSomeMsgToSomePerson(List<String> phoneNums, List<String> contents, String stime) throws SMSException {
		String phoneNumsCsv = MyStringUtils.listToCsv(phoneNums);
		String encodedContentCsv = MyStringUtils.listToCsv(contents);
		return this.sendMsg(phoneNumsCsv, encodedContentCsv, stime);
	}
	
	@SuppressWarnings("unchecked")
	private String sendMsg(String phoneNums, String contents, String stime) throws SMSException {
		
		MyAssert.notNull(phoneNums, "电话号码不能为空");
		MyAssert.notNull(contents, "短信内容不能为空");
		
		validatePhoneNumberFormat(phoneNums);
		
		List<String> encodedContentList = populateEncodedContentList(contents);
		
		if (stime == null) {
			stime = "";
		}
		
		String encodedContentCsv = MyStringUtils.listToCsv(encodedContentList);
		//短信发送
		String result_mt = null;
		if (encodedContentList.size() == 1) {
			result_mt = bucpClient.mdSmsSend_u(phoneNums, encodedContentCsv, "", stime, "");
		} else if(encodedContentList.size() > 1){
			bucpClient.gxmt(phoneNums, encodedContentCsv, "", stime, "");
		}
		
		if(result_mt == null || result_mt.startsWith("-")||result_mt.equals(""))//发送短信，如果是以负号开头就是发送失败。
		{
			//throw new SMSException("发送失败！返回值为："+result_mt+"请查看webservice返回值对照表");
			throw new SMSException(result_mt, "发送失败!");	
		}
		smsSendLogService.saveSendLog(clazz, phoneNums.split(","), encodedContentList.toArray(new String[] {}));
		//输出返回标识，为小于19位的正数，String类型的。记录您发送的批次。
		return result_mt;
	}

	private void validatePhoneNumberFormat(String phoneNums) {
		String[] phoneumsArray = phoneNums.split(",");
		boolean phoneNumberCheckOk = true;
		for (String phneNumber : phoneumsArray) {
			if (!phneNumber.matches("\\s*\\d{11}\\s*")) {
				phoneNumberCheckOk = false;
				break;
			}
		}
		
		MyAssert.isTrue(phoneNumberCheckOk, "手机号码的格式必须为csv格式，如13811111111,13811111112,13811111113");
	}
	
	private List<String> populateEncodedContentList(String contents) {
		//我们的Demo最后是拼成xml了，所以要按照xml的语法来转义
		if(contents.indexOf("&")>=0) {
			contents = contents.replace("&","&amp;");
		}
		
		if(contents.indexOf("<")>=0) {
			
		contents = contents.replace("<","&lt;");
			
		}
		if(contents.indexOf(">")>=0) {
			contents = contents.replace(">","&gt;");
		}
				
		List<String> encodedContentList = new ArrayList<String>();
		String[] contentsArray = contents.split(",");
		for (String content : contentsArray) {
			if(!content.endsWith("【易学网】")) 
				content = content + "【易学网】";
			try {
				String encodedContent = URLEncoder.encode(content, "GB2312");
				encodedContentList.add(encodedContent);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		return encodedContentList;
	}
	
	public void chargeFee(String cardno, String cardpwd) throws SMSException {
		MyAssert.notNull(cardno);
		MyAssert.notNull(cardpwd);
		String result_chargeFee = bucpClient.chargeFee(cardno, cardpwd);
		if (result_chargeFee == null || result_chargeFee.startsWith("-")||result_chargeFee.equals("")) {
			//throw new SMSException("充值失败！返回值为："+result_chargeFee+"请查看webservice返回值对照表");
			throw new SMSException(result_chargeFee, "充值失败!");	
		}
	}
	
	public String getBalance() {
		return bucpClient.getBalance(); 
	}
	
	public void register(SMSRegisterConfig smsRegisterConfig) throws SMSException {
		MyAssert.notNull(smsRegisterConfig, "注册信息类 smsRegisterConfig 不能为空");
		//如为第一次使用，请先注册，注册方法如下，为方便在后来的合作成功客服人员给您提供服务请如实填写下列信息
		//只需注册一次即可
		//返回值说明：注册成功返回0 注册成功
		String result_register = bucpClient.register(
				smsRegisterConfig.getProvince(), 
				smsRegisterConfig.getCity(), 
				smsRegisterConfig.getTrade(), 
				smsRegisterConfig.getEntname(), 
				smsRegisterConfig.getLinkman(), 
				smsRegisterConfig.getPhone(), 
				smsRegisterConfig.getMobile(), 
				smsRegisterConfig.getEmail(), 
				smsRegisterConfig.getFax(), 
				smsRegisterConfig.getAddress(), 
				smsRegisterConfig.getPostcode(), 
				smsRegisterConfig.getSign());
		
		if(result_register==null||result_register.equals(""))
		{
			//System.out.print("没有找到http://sdk2.zucp.net:8060/webservice.asmx，这个地址，您的系统可能是utf8,打开 Client.java 这个文件，请看第9到第16的注释");
		}
		
		if(result_register.startsWith("-"))
		{
			throw new SMSException(result_register, "注册失败");
		}
				
	}

	public void unRegister() throws SMSException {
		String result_unRegisterResult = bucpClient.UnRegister();
		if(result_unRegisterResult.startsWith("-"))
		{
			throw new SMSException(result_unRegisterResult, "注销失败");
		}
	}
	
	public void changeRegisterInfo(SMSRegisterConfig smsRegisterConfig) throws SMSException {
		this.unRegister();
		this.register(smsRegisterConfig);
	}
	
	public void changePwd(String newPwd) throws SMSException {
		MyAssert.notNull(newPwd);
		String result_udpPwd = bucpClient.UDPPwd(newPwd);
		if (result_udpPwd.startsWith("-")) {
			throw new SMSException(result_udpPwd, "修改密码失败");
		}
	}
}
